package com.mars.module.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mars.common.response.PageInfo;
import com.mars.common.result.R;
import com.mars.module.admin.entity.Activity;
import com.mars.module.admin.entity.Record;
import com.mars.module.admin.mapper.ActivityMapper;
import com.mars.module.admin.mapper.RecordMapper;
import com.mars.module.system.entity.SysUser;
import com.mars.module.system.mapper.SysUserMapper;
import com.mars.module.system.service.ISysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.mars.module.admin.request.AwardRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.mars.module.admin.mapper.AwardMapper;
import org.springframework.beans.BeanUtils;
import com.mars.module.admin.entity.Award;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mars.module.admin.service.IAwardService;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 奖项业务层处理
 *
 * @author mars
 * @date 2024-04-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class AwardServiceImpl implements IAwardService {

    private final AwardMapper baseMapper;
    private final ActivityMapper activityMapper;
    private final RecordMapper recordMapper;
    private final SysUserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Award add(AwardRequest request) {
        Award entity = Award.builder().build();
        BeanUtils.copyProperties(request, entity);
        Activity activity = activityMapper.selectById(entity.getActivityId());
        entity.setName(activity.getActivityName());
        entity.setCreateTime(new Date());
        baseMapper.insert(entity);
        return entity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Integer id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(List<Integer> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(AwardRequest request) {
        Award entity = Award.builder().build();
        BeanUtils.copyProperties(request, entity);
        Activity activity = activityMapper.selectById(entity.getActivityId());
        if (activity != null){
            entity.setName(activity.getActivityName());
        }
        return baseMapper.updateById(entity) > 0 ;
    }

    @Override
    public Award getById(Integer id) {
        return baseMapper.selectById(id);
    }

    @Override
    public PageInfo<Award> pageList(AwardRequest request) {
        Page<Award> page = new Page<>(request.getPageNo(), request.getPageSize());
        LambdaQueryWrapper<Award> query = this.buildWrapper(request);
        IPage<Award> pageRecord = baseMapper.selectPage(page, query);
        return PageInfo.build(pageRecord);
    }


    @Override
    public List<Award> list(AwardRequest request) {
        LambdaQueryWrapper<Award> query = this.buildWrapper(request);
        return baseMapper.selectList(query);
    }

    @Override
    public R<Award> lottery(Integer activityId, Long userId) {
        QueryWrapper<Record> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda().eq(Record::getActivityId, activityId)
                .eq(Record::getUserId, userId);
        //抽奖记录
        List<Record> records = recordMapper.selectList(recordQueryWrapper);
        //TODO 这里的3可以改为可设置的
        if (CollectionUtil.isNotEmpty(records) && records.size() >= 3){
            return R.error("没有抽奖次数啦!");
        }
        List<Award> awards = baseMapper.selectByActivityId(activityId);
        if (CollectionUtil.isEmpty(awards)){
            return R.error("已经没有奖品可以中了");
        }
        List<Award> awardList = awards.stream().filter(award -> award.getRemainCount() > 0).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(awardList)){
            return R.error("已经没有奖品可以中了");
        }
        Award award = drawLottery(awardList);
        //添加抽奖记录
        Record record = Record.builder().activityId(activityId).userId(userId).build();
        String activityName = awardList.get(0).getName();
        record.setActivityName(activityName);
        SysUser sysUser = userMapper.selectById(userId);
        record.setUserName(sysUser.getRealName());
        if (award == null){
            record.setIsAward(0);
            record.setAwardId(null);
            recordMapper.insert(record);
            return R.error("很遗憾您没有中奖！");
        }else {
            record.setIsAward(1);
            record.setAwardId(award.getId());
            record.setAwardName(award.getAward());
            recordMapper.insert(record);
        }
        return R.success(award);
    }

    @Override
    public R<List<Record>> getAward(Integer activityId, Long userId) {
        QueryWrapper<Record> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda().eq(activityId!=null,Record::getActivityId, activityId)
                .eq(Record::getUserId, userId);
        List<Record> records = recordMapper.selectList(recordQueryWrapper);
        return R.success(records);
    }

    private static final double WIN_PROBABILITY = 1; // 中奖概率

    public static Award drawLottery(List<Award> awardList) {
        Random random = new Random();
        // 生成一个0到1之间的随机数
        double randomValue = random.nextDouble();
        // 判断是否中奖
        if (randomValue < WIN_PROBABILITY) {
            // 如果中奖，随机抽取一个奖项
            int randomIndex = random.nextInt(awardList.size());
            return awardList.get(randomIndex);
        } else {
            return null;
        }
    }

    private LambdaQueryWrapper<Award> buildWrapper(AwardRequest param) {
        LambdaQueryWrapper<Award> query = new LambdaQueryWrapper<>();
        if (param.getActivityId() != null){
               query.eq(Award::getActivityId ,param.getActivityId());
        }
         if (StringUtils.isNotBlank(param.getName())){
               query.like(Award::getName ,param.getName());
        }
        if (param.getCount() != null){
               query.eq(Award::getCount ,param.getCount());
        }
         if (StringUtils.isNotBlank(param.getAward())){
               query.like(Award::getAward ,param.getAward());
        }
        return query;
    }

}
